/**
 * 
 */
package com.wistech.search.solr.score;

import java.io.IOException;

import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.FieldCache.DocTermsIndex;
import org.apache.solr.schema.SchemaField;

import com.wistech.utils.DocumentUtils;

/**
 * 表达式自定义评分器
 * 
 * @author Liuye
 * 
 */
@SuppressWarnings("serial")
public final class ExpressionXscorer implements Xscorer {
	private final ExpressionXscorerFactory xscorerFactory;
	private final SchemaField idField;
	private DocTermsIndex idDocTermsIndex;
	private final float similartyBoost;

	// private long[] scatterIndex;
	// private Map<String, float[]> innerDataIndex = Maps.newHashMap();
	//
	// private Map<Long, Float> scatterCountMap = Maps.newHashMap();
	// private String scatterFieldName;

	public ExpressionXscorer(ExpressionXscorerFactory xscorerFactory) {
		this.xscorerFactory = xscorerFactory;
		this.idField = xscorerFactory.getSchema().getUniqueKeyField();
		this.similartyBoost = xscorerFactory.getSimilarityBoost();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.solr.schema.Xscorer#score(java.lang.String,
	 * java.util.Map)
	 */
	@Override
	public float score(int doc, float score) {
		// 根据id获取实际评分因子
		String id = getIdValue(idDocTermsIndex, doc);// String.valueOf(doc);//
		// List<String> innerPropNames = xscorerFactory.getInnerExpression()
		// .getPropNames();
		// float innerScore = 0f;
		// if (innerPropNames != null && !innerPropNames.isEmpty()) {
		// Map<String, Object> env = Maps.newHashMap();
		// for (String propName : innerPropNames) {
		// if (!propName.startsWith("$")) {
		// float[] index = innerDataIndex.get(propName);
		// if (index != null) {
		// env.put(propName, index[doc]);
		// }
		// }
		// }
		// env.put("$score", score);
		// if (this.isScattered()) {
		// env.put("$scatter", this.scatter(doc));
		// }
		// innerScore = xscorerFactory.getInnerExpression().eval(env);
		// }
		// float bizScore = this.xscorerFactory.getBizScore(id);
		return score * this.similartyBoost
				+ this.xscorerFactory.getBizScore(id);

	}

	protected final String getIdValue(DocTermsIndex termsIndex, int doc) {
		return (String) DocumentUtils.getFieldValue(termsIndex,
				idField.getType(), doc);
	}

	@Override
	public void setNextReader(AtomicReaderContext context) throws IOException {
		idDocTermsIndex = FieldCache.DEFAULT.getTermsIndex(context.reader(),
				idField.getName());
		// if (isScattered()) {
		// scatterIndex = FieldCache.DEFAULT
		// .getLongs(reader, scatterFieldName);
		// }
		// List<String> innerPropNames = xscorerFactory.getInnerExpression()
		// .getPropNames();
		// if (innerPropNames != null && !innerPropNames.isEmpty()) {
		// for (String propName : innerPropNames) {
		// if (!propName.startsWith("$")) {
		// innerDataIndex.put(propName,
		// FieldCache.DEFAULT.getFloats(reader, propName));
		// }
		// }
		// }
	}

	// public boolean isScattered() {
	// return scatterFieldName != null && !"".equals(scatterFieldName.trim());
	// }
	//
	// public float scatter(int doc) {
	// final long scatterValue = scatterIndex[doc];
	// if (scatterCountMap.containsKey(scatterValue)) {
	// float count = scatterCountMap.get(scatterValue);
	// count++;
	// scatterCountMap.put(scatterValue, count);
	// return 100F / count;
	// } else {
	// scatterCountMap.put(scatterValue, 1f);
	// return 100F;
	// }
	// }

	// public String getScatterFieldName() {
	// return this.scatterFieldName;
	// }
	//
	// public void setScatterFieldName(String fieldName) {
	// this.scatterFieldName = fieldName;
	// }
}
